[% setvar title TITLE %]
<div id="archive-notice">
    <h3>This file is part of the Perl 6 Archive</h3>
    <p>To see what is currently happening visit <a href="http://www.perl6.org/">http://www.perl6.org/</a></p>
</div>
<div class='pod'>
<a name='TITLE'></a><h1>TITLE</h1>
<p>Merge <code>$!</code>, <code>$^E</code>, <code>$@</code> and <code>$?</code></p>
<a name='VERSION'></a><h1>VERSION</h1>
<pre>  Maintainer: Peter Scott &lt;<a href='mailto:peter@psdt.com'>peter@psdt.com</a>&gt;
  Date: 25 Aug 2000
  Last Modified: 3 Oct 2000
  Mailing List: <a href='mailto:perl6-language-errors@perl.org'>perl6-language-errors@perl.org</a>
  Number: 151
  Version: 4
  Status: Frozen</pre>
<a name='ABSTRACT'></a><h1>ABSTRACT</h1>
<p>The distinction between the <code>$!</code>, <code>$^E</code>, <code>$@</code> and <code>$?</code> variables is no
longer worth trading for the benefits to be gained from merging them together.</p>
<a name='DESCRIPTION'></a><h1>DESCRIPTION</h1>
<p>The <code>$!</code> variable made excellent sense in Perl 4 as a representation of
the Unix C RTL <code>errno</code>.  It went right along with the tight integration
and close mapping between Perl and sections 2 and 3 of the Unix manual.</p>
<p>The amount of third-party code published via CPAN made possible by the
module features of Perl 5, and the likelihood of exception handling gaining
increased importance in Perl 6 both serve to make the distinction between
errors for which <code>$!</code> is set and those it isn't, less useful.</p>
<p>Non-system code throws exceptions by <code>die</code>ing and any code that handles
those exceptions reads the reasons in the <code>$@</code> variable.  Why have two
classes of errors where failure reasons are passed in different variables
when the distinction between those classes may appear irrelevant (not a
Unix platform) or arbitrary (what is a &quot;system error&quot; and why should it be
set for a failed <code>open</code> but not, say, for a failed <code>new IO::Socket</code>?)?</p>
<p>Hence this proposal is to merge all these together into a single
out-of-band indicator of error, so that users don't have to check multiple
variables in the case of an <code>eval</code>.</p>
<a name='IMPLEMENTATION'></a><h1>IMPLEMENTATION</h1>
<p>Merge all these variables into one.  Say for the sake of argument that it
is <code>$!</code> (for the mnemonic value of &quot;something went bang&quot;).  This variable
will <i>always</i> be an object.  An attribute will determine whether it is
something that can be caught or could cause a <code>die</code>; this will be checked
by code implementing exception handling (like, say, RFC 88).  Call this
attribute <code>is_exception</code> for the sake of argument.</p>
<p>It should be possible to make the same attribute fulfil and extend the
requirement of RFC 70 to make <code>Fatal.pm</code> applicable throughout the core
and optionally to user modules.</p>
<p>Note that if RFC 88 passes, it requires <code>$@</code> to become a structured object
anyway; this RFC simply proposes using the same object for other errors as
well.</p>
<p>What about situations where more than one of the current set of four
variables might be set?  Well, note that <code>$^E</code> is just an extension of
<code>$!</code>, so we can consider those two variables collapsed into <code>$!</code>.  The
following cases obtain:</p>
<pre>    Perl would    |    The error variable is currently
    currently set |Non-existent: |Existent, and is_exception is
                  |create new one|    true      |    false
                  |setting its   |              |
                  |is_exception  |              |
    ==============|==============|==============|===============
        $!, $^E   | Depends on   | Overwrite,   |
                  | Fatal.pm     | but see      |
                  | applicability| discussion   |  Overwrite
    --------------+--------------+ below        |
         $?       | False        |              |
    --------------+--------------+--------------+---------------
         $@       | True         | New one links| New one links
                  |              | to previous  | to previous
                  |              | per RFC 88   | via sysmsg</pre>
<p>The one case that needs special attention is (assuming RFC 88 passes) when
the variable is holding a current exception and a non-exception error
occurs.  Furthermore, the only place this is a problem is <code>catch</code> and
<code>finally</code> blocks (see RFC 88).  It cannot occur in a <code>try</code> block because
as soon as anything would create an exception, it will cause control to
leave the <code>try</code> block.</p>
<p>In a <code>catch</code> block, the exception is to be cleared at the end of the block
anyway so overwriting it with a non-exception error would not cause a
problem for control flow.  In a <code>finally</code> block, any current exception
needs to be preserved at the end of the block, therefore it cannot be
overwritten; but Perl could save the exception on entry to the <code>finally</code>
block and restore it on exit.  The one remaining issue is how the user can
access the current exception in a <code>catch</code> or <code>finally</code> block after a
non-exception error.  In this arguably rare case, they could get it from
the first element of the
<code>@@</code> array, which RFC 88 defines as the exception stack.</p>
<p>To expand upon parts of the above table:</p>
<p>After a failed <code>system</code>, <code>``</code> or anything else that currently sets <code>$?</code>:
the variable will be created with the <code>is_exception</code> attribute false.  In
a numeric or string context, the variable will be the number that would
currently be placed in <code>$?</code>.  If the variable already existed, then if
<code>is_exception</code> was false, it is overwritten, otherwise see the discussion
above.</p>
<p>On a failed system call (something that currently sets <code>$!</code>; not a
<code>system</code> call): the variable will be created with the <code>is_exception</code>
attribute false.  The value of the variable in numeric and string contexts
will be the same as what would currently be placed in <code>$!</code>.  Where the
<code>$^E</code> variable would currently be set, set a <code>extra_info</code> attribute or
some such.  (We could actually use the <code>sysmsg</code> attribute, but that might
confuse people traversing linked errors who expect that always to be a
reference or undef.)  If the variable already existed, then if
<code>is_exception</code> was false, it is overwritten, otherwise see the discussion
above.</p>
<p>On a <code>throw</code> or <code>die</code>: the variable will be created with the
<code>is_exception</code> attribute true.  If the variable previously existed with a
<code>is_exception</code> value of false, a link to the previous value will be
provided in the <code>sysmsg</code> attribute.  RFC 88 details how and under what
circumstances the variable is linked to a previous version which had
<code>is_exception</code> true.</p>
<a name='Impact on RFC 88'></a><h2>Impact on RFC 88</h2>
<p>If the variable chosen is <code>$@</code>, no impact.  If the variable chosen is
<code>$!</code>, then <code>$@</code> needs to be changed to <code>$!</code>.  The implementation of RFC
88 will need to check not merely for the existence of the error variable
but whether its <code>is_exception</code> attribute is set to know whether there is a
current exception.</p>
<a name='REFERENCES'></a><h1>REFERENCES</h1>
<p><i><a href='http://search.cpan.org/perldoc?perlvar#Error Indicators'>&quot;Error Indicators&quot; in perlvar</a></i></p>
<p>RFC 88: Structured Exception Handling Mechanism (Try)</p>
<p>RFC 80: Exception objects and classes for builtins</p>
<p>RFC 70: Allow exception-based error reporting</p>
</div>
